﻿using System;
using System.Collections.Generic;
using TrainGame.AI.TileLay;
using TrainGame.Common;

namespace TrainGame.Model
{
	/// <summary>
	/// Holds a complete game board - split out so tile and route AI can create and evaluate temporary game board setups
	/// 
	/// TODO: replace Game.GameboardHexes with Game.Gameboard
	/// 
	/// </summary>
	[Serializable]
	public class Gameboard
	{
		public GameboardHexCollection GameboardHexes;

		public Gameboard()
		{
			GameboardHexes = new GameboardHexCollection();
		}

		public Gameboard MakeCopy()
		{
			Gameboard copy = new Gameboard();
#if doesnt_work
			XmlSerializer serializer = new XmlSerializer(typeof(GameboardHex));
			using (MemoryStream memstream = new MemoryStream())
			{
				foreach (GameboardHex hex in this.GameboardHexes)
				{
					// copy a GameBoardHex by serializing to memory stream, then deserializing into a copy
					memstream.Position = 0;
					serializer.Serialize(memstream, hex);	// write it (overwrites old contents)
					memstream.Position = 0;

					GameboardHex copyHex = serializer.Deserialize(memstream) as GameboardHex;	// read it
					copyHex.Button = null;  // copy shouldn't link back to UI

					copy.GameboardHexes.Add(copyHex);
				}
			}
#endif
			foreach (GameboardHex hex in this.GameboardHexes)
			{
				copy.GameboardHexes.Add (hex.MakeCopy());
				//GameboardHex newHex = hex.MakeCopy();
				//copy.GameboardHexes[newHex.Location] = newHex;
			}

			return copy;
		}

		[NonSerialized] private GameboardHex origHex;
		[NonSerialized] private Tile origTile;
		[NonSerialized] private int origRot;
		[NonSerialized] private TrackSegment[] origTrackSegments;

		public void ApplyTileLayWithUndo(AiTileLay tileLay)
		{
			origHex = GameboardHexes[tileLay.Hex.Location];
			origTile = tileLay.Hex.Tile;
			origRot = tileLay.Hex.Rotation;
			origTrackSegments = tileLay.Hex.TrackSegments;

			GameboardHexes[tileLay.Hex.Location] = tileLay.Hex;	// put the temporary hex into the hex map
			tileLay.Hex.Tile = tileLay.Tile;
			tileLay.Hex.Rotation = tileLay.Rotation;
			tileLay.Hex.TemporarilyTransferTileRoutesToHex();			// writes NewRoutes
			TrackSegment.CalculateHexRoutesFromNewRoutes(tileLay.Hex);	// reads NewRoutes
		}

		public void UndoTileLay(AiTileLay tileLay)
		{
			tileLay.Hex.Tile = origTile;
			tileLay.Hex.Rotation = origRot;
			tileLay.Hex.TrackSegments = origTrackSegments;
			GameboardHexes[tileLay.Hex.Location] = origHex;
		}

		/// <summary>
		/// Print all the tile connectivity to the visual studio Output window.  Useful for debugging.
		/// </summary>
		public void DumpMap()
		{
			List<string> lines = new List<string>();

			foreach (GameboardHex hex in GameboardHexes)
			{
				string line = null;

				if (hex.HexType == GameboardHex.eHexType.OffBoard)
				{
					line = string.Format("Hex {0}, Offboard, city {1} ${2}", hex.Location,
						TrackSegment.MakeCityName(hex), hex.Value);
				}
				else if (hex.Tile != null)
				{
					line = string.Format("Hex {0}, tile {1}", hex.Location, hex.Tile.Name);

					if (hex.TownType != GameboardHex.eTownType.None)
						line += string.Format(", city {0} ${1}", TrackSegment.MakeCityName(hex), hex.Value);
				}

				if (line != null)
				{
					if ((hex.TrackSegments != null) && (hex.TrackSegments.Length > 0))
					{
						line += ", tracks: ";
						bool first = true;
						foreach (TrackSegment track in hex.TrackSegments)
						{
							if (!first)
								line += ", ";
							line += track.ToString();
							first = false;
						}
					}
					lines.Add(line);
				}
			}

			lines.Sort();
			foreach (string line in lines)
				XTrace.Trace(line);
		}
	}
}
